package com.fan.shop.views.bean;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.el.ValueExpression;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

import org.apache.log4j.Logger;

import com.fan.shop.businesslogic.CategoryDeleteProcess;
import com.fan.shop.businesslogic.CategoryEditProcess;
import com.fan.shop.domain.Category;
import com.fan.shop.services.CategoryService;

@ManagedBean(name = "categoriesTree")
@RequestScoped
public class CategoriesTreeBean extends ShopBean{

	private static Logger logger = Logger.getLogger(CategoriesTreeBean.class);

	@ManagedProperty(value = "#{categoryService}")
	private CategoryService categoryService;

	private List<Category> categories;
	private HtmlOutputText categoryTreeHtml;

	private String addCategoryName;
	private String addCategoryDescription;
	private String addCategoryParent;

	private String editCategoryName;
	private String editCategoryDescription;
	private String editCategoryParent;

	private List<String> categoriesList;

	public CategoriesTreeBean() {
		// TODO Auto-generated constructor stub
	}

	public CategoryService getCategoryService() {
		return categoryService;
	}

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public List<Category> getCategories() {
		logger.debug("getCategories()");

		categories = categoryService.getAllCategories();
		logger.debug("getCategories()  Size: " + categories.size());
		return categories;
	}

	public void setCategories(List<Category> categories) {
		this.categories = categories;
	}

	public HtmlOutputText getCategoryTreeHtml() {

		FacesContext context = FacesContext.getCurrentInstance();
		HtmlOutputText output = new HtmlOutputText();
		ValueExpression value = context
				.getApplication()
				.getExpressionFactory()
				.createValueExpression(context.getELContext(),
						"#{categories.categoryTreeHtml }", String.class);
		output.setValueExpression("value", value);

		// String html = buildTree(categoryService,
		// categoryService.getCategory("Clothe"));
		// html = "<ul id=\"browser\" class=\"filetree\">" + html + "</ul>";

		String html = "";
		for (Category cat : categoryService.getRootCategories()) {
			String allHtml = buildTree(categoryService, cat);
			allHtml = "\n<ul>\n" + allHtml + "\n</ul>\n";
			html += allHtml;

		}
		html = "<ul id=\"browser\" class=\"filetree\">" + html + "</ul>";

		output.setValue(html);
		categoryTreeHtml = output;

		return categoryTreeHtml;
	}

	public void setCategoryTreeHtml(HtmlOutputText categoryTreeHtml) {

		this.categoryTreeHtml = categoryTreeHtml;
	}

	public String getAddCategoryName() {
		return addCategoryName;
	}

	public void setAddCategoryName(String addCategoryName) {
		this.addCategoryName = addCategoryName;
	}

	public String getAddCategoryDescription() {
		return addCategoryDescription;
	}

	public void setAddCategoryDescription(String addCategoryDescription) {
		this.addCategoryDescription = addCategoryDescription;
	}

	public String getAddCategoryParent() {
		return addCategoryParent;
	}

	public void setAddCategoryParent(String addCategoryParent) {
		this.addCategoryParent = addCategoryParent;
	}

	public String getEditCategoryName() {
		if (editCategoryName != null && editCategoryName.length() > 0) {
			editCategoryDescription = categoryService.getCategory(
					editCategoryName).getDescription();
			editCategoryParent = categoryService
					.getCategoryNameByID(categoryService.getCategory(
							editCategoryName).getParent());
		}
		return editCategoryName;
	}

	public void setEditCategoryName(String editCategoryName) {
		this.editCategoryName = editCategoryName;
	}

	public String getEditCategoryDescription() {
		return editCategoryDescription;
	}

	public void setEditCategoryDescription(String editCategoryDescription) {
		this.editCategoryDescription = editCategoryDescription;
	}

	public String getEditCategoryParent() {
		return editCategoryParent;
	}

	public void setEditCategoryParent(String editCategoryParent) {
		this.editCategoryParent = editCategoryParent;
	}

	public List<String> getCategoriesList() {
		categoriesList = new ArrayList<String>();
		for (Category cat : categoryService.getAllCategories()) {
			categoriesList.add(cat.getName());
		}
		return categoriesList;
	}

	public void setCategoriesList(List<String> categoriesList) {
		this.categoriesList = categoriesList;
	}

	public String buildTree(CategoryService service, Category category) {
		if (service.isLeaf(category)) {
			return "\n<li><span class=\"file\">" + category.getName()
					+ "</span></li>\n";
		}
		String result = "";

		result = "\n<li>\n<span class=\"folder\">" + category.getName()
				+ "</span>\n";
		for (Category cat : service.getSubCategories(category)) {

			result += "<ul>\n" + buildTree(service, cat) + "\n</ul>";

		}

		return result + "</li>";
	}

	public String addCategoryAction() {

		Map<String, String> map = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap();
		editCategoryName = map.get("form:add_category_name");
		editCategoryDescription = map.get("form:add_category_description");
		editCategoryParent = map.get("form:add_category_parent");
		if (editCategoryName.length() == 0
				|| editCategoryDescription.length() == 0) {
			return "management/categoriesTree";
		}

		Category newCategory = new Category();
		newCategory.setName(editCategoryName);
		newCategory.setDescription(editCategoryDescription);
		newCategory.setParent(categoryService.getCategory(editCategoryParent)
				.getId());

		categoryService.addCategory(newCategory);

		clearForm();

		return "management/categoriesTree";

	}

	public String updateCategoryAction() {

		CategoryEditProcess categoryEditProcess = new CategoryEditProcess();
		categoryEditProcess.setCategoryService(categoryService);
		categoryEditProcess.setName(editCategoryName);
		categoryEditProcess.setDescription(editCategoryDescription);
		categoryEditProcess.setParent(editCategoryParent);
		categoryEditProcess.process();
		return "management/categoriesTree";
	}

	public String deleteCategoryAction() {

		CategoryDeleteProcess categoryDeleteProcess = new CategoryDeleteProcess();
		categoryDeleteProcess.setCategoryService(categoryService);
		categoryDeleteProcess.setName(editCategoryName);

		int returenValue = categoryDeleteProcess.process();

		editCategoryName = "";
		editCategoryDescription = "";
		editCategoryParent = "";

		return "management/categoriesTree";
	}

	public void loadCategoryAction(AjaxBehaviorEvent event) {

		Map<String, String> map = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestParameterMap();
		editCategoryName = map.get("form:edit_name");

		System.out.println(editCategoryName);
		Category category = categoryService.getCategory(editCategoryName);

		editCategoryDescription = category.getDescription();
		editCategoryParent = categoryService.getCategoryNameByID(category
				.getParent());

	}

	public void clearForm() {
		addCategoryName = "";
		addCategoryDescription = "";
		addCategoryParent = "";
	}
}
